package services.security;

import java.util.*;

import dto.*;
import dto.api.ApiAuthInfoDto;

import services.exception.*;
import utils.*;
import models.*;
import models.application.*;
import models.pubobj.AniObjectState;

public class AniApiAuthService extends AniSecurityService {

	//API authentication
	//-auth info
	public static AniApiAppRel checkApiAuthInfoLegality(ApiAuthInfoDto apiAuthInfo) {
		checkReqIdLegality(apiAuthInfo.reqId);
		AniApiAppRel apiAppRel = checkAppApiRelLegality(apiAuthInfo);
		checkApiAppRelState(apiAppRel);
		checkApiTokenLegality(apiAppRel, apiAuthInfo);
		
		return apiAppRel;
	}
	private static AniApiAppRel checkAppApiRelLegality(ApiAuthInfoDto apiAuthInfo){
		AniApiAppRel apiAppRel = AniApiAppRel.withClientAppIdTargetApiId(apiAuthInfo.clientAppId, apiAuthInfo.targetApiId);
		if(apiAppRel == null){
			throw new AniAuthException("APP_API_REL_ILLEGAL");
		}
		
		return apiAppRel;
	}
	private static void checkApiAppRelState(AniApiAppRel apiAppRel){
		if(!apiAppRel.state.stateKey.equals(AniObjectState.States.ACTIVATED.name())) {
			throw new AniAuthException("APP_API_NOT_ACTIVATED");
		}
	}
	private static void checkApiTokenLegality(AniApiAppRel apiAppRel, ApiAuthInfoDto apiAuthInfo) {
		String apiAuthCodeMD5 = getApiAuthCodeMD5(apiAppRel, apiAuthInfo);
		if(!apiAuthInfo.authCode.equals(apiAuthCodeMD5)){
			throw new AniAuthException("APP_API_AUTH_FAILED");
		}
	}
	//--get server-side api auth code
	private static String getApiAuthCodeMD5(AniApiAppRel apiAppRel, ApiAuthInfoDto apiAuthInfo) {
		
		String md5Token = apiAppRel.clientApp.token;
		String serverAuthCode = 
				apiAuthInfo.clientAppId.toString()
				+ apiAuthInfo.targetApiId.toString()
				+ md5Token
				+ apiAuthInfo.reqId.toString();
		String serverAuthCodeMD5 = SecureUtils.generateMD5String(serverAuthCode);
		
		return serverAuthCodeMD5;
	}
	//-params legality
	public static void checkApiRequiredParams(AniApi aniApi, Map<String, String> containedParams){
		List<AniApiParam> params = aniApi.params;
		for(AniApiParam oneParam: params){
			if(!containedParams.containsKey(oneParam.paramName)){
				throw new AniAuthException("REQUIRED_PARAMS_CANNOT_BE_FOUND");
			}
		}
	}
	
	
	
}